﻿using System;
using System.Windows.Media;
using System.Windows.Media.Media3D;

using SBPweb.Presentation.CompleteMesh.Utils;

namespace SBPweb.Presentation.CompleteMesh.Primitives
{
    
    public abstract class MeshBase
    {

        #region Protected members

        protected MeshGeometry3D pMesh;
        protected Vector3D pTextureVector;
        protected Textures.TextureCoordinateGeometries pTextureCoordinateGeometry;

        #endregion

        #region Constructor logic

        public MeshBase()
        {
            pMesh = new MeshGeometry3D();
            pTextureVector = new Vector3D(0, 0, 1);
            pTextureCoordinateGeometry = Textures.TextureCoordinateGeometries.Planar;
        }

        #endregion

        #region Public property accessors

        public Rect3D Bounds
        {
            get
            {
                return pMesh.Bounds;
            }
        }

        public Vector3DCollection Normals
        {
            get
            {
                return pMesh.Normals;
            }
        }

        public Point3DCollection Positions
        {
            get
            {
                return pMesh.Positions;
            }
        }

        public PointCollection TextureCoordinates
        {
            get
            {
                return pMesh.TextureCoordinates;
            }
        }

        public Textures.TextureCoordinateGeometries TextureCoordinateGeometry
        {
            get
            {
                return pTextureCoordinateGeometry;
            }
            set
            {
                pTextureCoordinateGeometry = value;
                ApplyTextureCoordinates();
            }
        }

        public Vector3D TextureVector
        {
            get
            {
                return pTextureVector;
            }
            set
            {
                pTextureVector = value;
            }
        }

        public Int32Collection TriangleIndices
        {
            get
            {
                return pMesh.TriangleIndices;
            }
        }

        public Geometry3D GeometryInstance
        {
            get
            {
                return pMesh;
            }
        }

        #endregion

        #region Methods

        protected abstract void CalculateGeometry();

        protected virtual void InitializeCollections()
        {
            if (pMesh.Positions == null)
            {
                pMesh.Positions = new Point3DCollection();
            }
            if (pMesh.TextureCoordinates == null)
            {
                pMesh.TextureCoordinates = new PointCollection();
            }
            if (pMesh.TriangleIndices == null)
            {
                pMesh.TriangleIndices = new Int32Collection();
            }

            if (pMesh.Positions.Count > 0)
            {
                pMesh.Positions.Clear();
            }
            if (pMesh.TextureCoordinates.Count > 0)
            {
                pMesh.TextureCoordinates.Clear();
            }
            if (pMesh.TriangleIndices.Count > 0)
            {
                pMesh.TriangleIndices.Clear();
            }
        }

        protected virtual void ApplyTextureCoordinates()
        {
            pMesh.TextureCoordinates = Textures.GenerateTextureCoordinatesByGeometry(pTextureCoordinateGeometry, pMesh, pTextureVector);
        }

        #endregion

    }
}